﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using System.Xml;
using Autodesk.RevitAddIns;
using Sharper.Utils;
using Ucd.Core.StdDot;
using Ucd.Core.StdDot.ConfigExt;

namespace Sharper
{
    public partial class MainForm : Form
    {
        #region addin文件tab页的变量

        const string addinTab_ColumnVersion = "ColumnVersion"; //调试tab页，版本列
        const string addinTab_ColumnDebug = "ColumnDebug"; //调试tab页，debug列
        const string addinTab_ColumnRelease = "ColumnRelease"; //调试tab页，release列
        const string addinTab_ColumnAddin = "ColumnAddin"; //调试tab页，addin列

        #endregion

        #region csproj文件tab页的变量

        const string csprojTab_ColumnVersion = "ColumnVersion2"; //同步tab页，版本列
        const string csprojTab_ColumnSync = "ColumnSync"; //同步tab页，同步源列

        #endregion


        #region 构造函数

        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            string strXmlPath = Environment.CurrentDirectory + "\\SharperStudio.xml";


            //从配置文件更新 by:Zcb 2022-03-21 22:26
            {
                IniFile profile = new IniFile(TheAppBase.DefaultIniPath);
                const string curField = "Common";
                profile.GetValueOfKey(curField, "LastCfgPath", ref strXmlPath);
            }


            //初始化XML
            strXmlPath = strXmlPath.Trim();
            if (XMLUtil.EnsureXMLFile(strXmlPath))
            {
                textBoxPath.Text = strXmlPath;
                XMLUtil.xmlCfgPath = strXmlPath;


                //根据配置文件的内容渲染出GridView
                DrawGridView();
            }
            else
            {
                labelInfo.Text = "配置文件缺失！";
                labelInfo2.ForeColor = Color.Red;
            }
        }

        #endregion

        #region addin文件替换tab页

        /// <summary>
        /// addin文件替换
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GridViewAddin_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            //检查是否选择了XML路径
            if (string.IsNullOrEmpty(textBoxPath.Text))
            {
                labelInfo.Text = "请选择XML文件所在的文件夹！";
                labelInfo2.ForeColor = Color.Red;
                return;
            }

            //1. 获得该按钮所在行的版本号
            string version = GridViewAddin.Rows[e.RowIndex].Cells[addinTab_ColumnVersion].Value.ToString();

            //2. 获得该按钮所在列的执行状态
            string state = GridViewAddin.Columns[e.ColumnIndex].Name;
            string xmlNodeName = null;
            if (state == addinTab_ColumnDebug)
            {
                xmlNodeName = XMLUtil.DebugPathNode;
            }

            if (state == addinTab_ColumnRelease)
            {
                xmlNodeName = XMLUtil.ReleasePathNode;
            }

            //3. 获得配置文件中项目名称
            XmlNode XmlNode = XMLUtil.GetXmlNode(XMLUtil.xmlCfgPath, XMLUtil.ProjectNameNode);
            string dllName = XmlNode.InnerText.Trim();

            //4.1 获得目标路径
            string addinPath = "";
            List<RevitProduct> allRevits = RevitProductUtility.GetAllInstalledRevitProducts(); //获得revit版本

            if (allRevits == null || allRevits.Count == 0)
            {
                labelInfo.Text = "当前PC没有安装revit！";
                labelInfo2.ForeColor = Color.Red;
                return;
            }

            //4.2 拼接所有revit版本下的addin文件的路径
            foreach (RevitProduct rvt in allRevits)
            {
                string revitVersion = "Revit" + version;
                if (revitVersion.Equals(rvt.Version.ToString(), StringComparison.OrdinalIgnoreCase))
                {
                    addinPath = Path.Combine(rvt.AllUsersAddInFolder, dllName + ".addin");
                }
            }

            //5. 执行方法(如果点击按钮为Addin列，则需要执行删除方法，其余列为Copy方法)
            if (state == addinTab_ColumnAddin)
            {
                if (AddinFileUtil.DeleteAddinFile(addinPath))
                {
                    labelInfo.Text = version + "版本的addin文件移除成功！";
                    labelInfo2.ForeColor = Color.ForestGreen;
                }
                else
                {
                    labelInfo.Text = version + "版本的addin文件移除失败！请检查配置文件中的路径信息！";
                    labelInfo2.ForeColor = Color.Red;
                }
            }

            if (state == addinTab_ColumnDebug || state == addinTab_ColumnRelease)
            {
                string sourcePath = Path.Combine(Environment.CurrentDirectory, dllName + ".addin");
                if (!AddinFileUtil.CopyAddinFile(sourcePath, addinPath))
                {
                    labelInfo.Text = "替换文件失败！请检查配置文件中的路径信息！";
                    labelInfo2.ForeColor = Color.Red;
                    return;
                }

                //获得dll文件的路径
                string dllPath = XMLUtil.GetXmlNodeOfAttribute(XMLUtil.xmlCfgPath, XMLUtil.RootNode, xmlNodeName, version);

                //判断是否为相对路径
                if (PathUtils.IsRelativePath(dllPath))
                {
                    dllPath = PathUtils.GetFullPath(dllPath); //若为相对路径，则转换成绝对路径
                }

                //修改addin文件
                XMLUtil.ChangeXml(addinPath, dllPath);

                labelInfo.Text = "成功将addin文件替换为" + version + "-" + state.Substring(6, state.Length - 6) + "版本！";
                labelInfo2.ForeColor = Color.ForestGreen;
            }
        }

        #endregion

        #region 同步csproj版本tab页

        /// <summary>
        /// 同步csproj
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonSync_Click(object sender, EventArgs e)
        {
            //检查是否选择了XML路径
            if (string.IsNullOrEmpty(textBoxPath.Text))
            {
                labelInfo.Text = "请选择XML文件所在的文件夹！";
                labelInfo2.ForeColor = Color.Red;
                return;
            }

            //获得勾选行的版本号
            string version = "";
            for (int i = 0; i < GridViewSync.Rows.Count; i++)
            {
                if (Convert.ToBoolean(GridViewSync.Rows[i].Cells[csprojTab_ColumnSync].EditedFormattedValue))
                {
                    version = GridViewSync.Rows[i].Cells[csprojTab_ColumnVersion].Value.ToString();
                    break;
                }
            }

            if (string.IsNullOrEmpty(version))
            {
                labelInfo2.Text = "请先选择同步源！";
                labelInfo2.ForeColor = Color.Red;
                return;
            }

            //获得该版本号的路径
            string csprojPath = XMLUtil.GetXmlNodeOfAttribute(XMLUtil.xmlCfgPath, XMLUtil.RootNode, XMLUtil.CsprojPathNode, version);

            //判断是否为相对路径
            if (PathUtils.IsRelativePath(csprojPath))
            {
                csprojPath = PathUtils.GetFullPath(csprojPath); //若为相对路径，则转换成绝对路径
            }

            if (!File.Exists(csprojPath))
            {
                labelInfo2.Text = "同步失败，请检查配置中的csproj路径！";
                labelInfo2.ForeColor = Color.Red;
                return;
            }

            //获得配置文件中版本信息
            XmlNode XmlNode = XMLUtil.GetXmlNode(XMLUtil.xmlCfgPath, XMLUtil.RevitVersionNode);

            XmlNodeList versionList = XmlNode.ChildNodes;

            //获得其他版本的名称
            List<string> versionNameList = new List<string>();
            foreach (XmlNode versionNode in versionList)
            {
                //将节点转换为元素，便于得到节点的属性值
                XmlElement versionElement = (XmlElement) versionNode;

                if (versionElement.InnerText == version)
                {
                    continue;
                }

                versionNameList.Add(versionElement.InnerText);
            }

            //获得其他版本的路径信息
            List<string> versionPathList = new List<string>();
            foreach (string name in versionNameList)
            {
                string path = XMLUtil.GetXmlNodeOfAttribute(XMLUtil.xmlCfgPath, XMLUtil.RootNode, XMLUtil.CsprojPathNode, name);
                versionPathList.Add(path);
            }

            if (versionPathList.Count == 0)
            {
                labelInfo2.Text = "同步失败，请检查配置中的csproj路径！";
                labelInfo2.ForeColor = Color.Red;
                return;
            }

            foreach (var str in versionPathList)
            {
                if (!File.Exists(str))
                {
                    labelInfo2.Text = "同步失败，请检查配置中的csproj路径！";
                    labelInfo2.ForeColor = Color.Red;
                    return;
                }
            }

            //获得所选同步源的xmlNode
            List<XmlNode> xmlNodeList = XMLUtil.GetCsprojNode(csprojPath);

            //同步到其他版本
            foreach (var path in versionPathList)
            {
                //判断是否为相对路径
                string newPath = path;
                if (PathUtils.IsRelativePath(path))
                {
                    newPath = PathUtils.GetFullPath(path); //若为相对路径，则转换成绝对路径
                }

                XMLUtil.InsertCsprojNode(newPath, xmlNodeList);
            }

            labelInfo2.Text = "同步成功！";
            labelInfo2.ForeColor = Color.ForestGreen;
        }

        /// <summary>
        /// 勾选同步源时，只能勾选一项
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GridViewCsproj_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (Convert.ToBoolean(GridViewSync.Rows[e.RowIndex].Cells[csprojTab_ColumnSync].Value))
            {
                GridViewSync.Rows[e.RowIndex].Cells[csprojTab_ColumnSync].Value = false;
            }
            else
            {
                for (int i = 0; i < GridViewSync.Rows.Count; i++)
                {
                    GridViewSync.Rows[i].Cells[csprojTab_ColumnSync].Value = i == e.RowIndex;
                }
            }
        }

        /// <summary>
        /// 超链接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            linkLabel1.LinkVisited = true;
            Process.Start("IExplore", "https://jq.qq.com/?_wv=1027&k=LHLHPhFr");
        }

        #endregion

        #region 内部方法

        /// <summary>
        /// 根据配置文件的内容渲染出GridView
        /// </summary>
        private bool DrawGridView()
        {
            //获得配置文件中版本信息
            XmlNode XmlNode = XMLUtil.GetXmlNode(XMLUtil.xmlCfgPath, XMLUtil.RevitVersionNode);

            XmlNodeList versionList = XmlNode.ChildNodes;

            AddGridViewRowHead(GridViewAddin, versionList);
            AddGridViewRowHead(GridViewSync, versionList);

            return true;
        }

        /// <summary>
        /// 添加GridView的行表头
        /// </summary>
        /// <param name="gridView"></param>
        /// <param name="rowHeadList"></param>
        /// <returns></returns>
        private bool AddGridViewRowHead(DataGridView gridView, XmlNodeList versionList)
        {
            foreach (XmlNode versionNode in versionList)
            {
                //将节点转换为元素，便于得到节点的属性值
                XmlElement versionElement = (XmlElement) versionNode;

                //添加行
                int index = gridView.Rows.Add();
                gridView.Rows[index].Cells[0].Value = versionElement.InnerText;
            }

            return true;
        }

        #endregion

        private void buttonGlance_Click(object sender, EventArgs e)
        {
            string[] aa = FileOpUtil.ChooseOpenFile("选择配置文件", "*.xml", false);
            if (aa.Length != 0)
            {
                textBoxPath.Text = aa[0];
                XMLUtil.xmlCfgPath = aa[0];
            }
        }

        private void btnOpenCfgDir_Click(object sender, EventArgs e)
        {
            var dir = PathDirUtil.GetParentDir(textBoxPath.Text);
            PathDirUtil.OpenDir(dir);
        }

        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            IniFile profile = new IniFile(TheAppBase.DefaultIniPath);
            const string curField = "Common";
            profile.SetValueOfKey(curField, "LastCfgPath", XMLUtil.xmlCfgPath);
        }
    }
}